var HoverTranslate = {
	x : 0,
	y : 0,
	localx : 0,
	localy : 0,
	x2 : 0,
	y2 : 0,
	timer : null,
	wordTarget : null,
	translation : '',
	prefManager : null,
	detectKey : null,
	enabled : true,
	trans_visible : false,
	load : function() {
		HoverTranslate.log('starting load');
		HoverTranslate.prefManager = Components.classes["@mozilla.org/preferences-service;1"]
				.getService(Components.interfaces.nsIPrefBranch);
		//Check if this is the first time to use the addon
		var firstTime = HoverTranslate.prefManager
				.getBoolPref("extensions.hovertranslate.first.time");
		var currentversion = HoverTranslate.prefManager
				.getCharPref("extensions.hovertranslate.version");
		HoverTranslate.log('FirstTime::' + firstTime);
		HoverTranslate.log('currentversion::' + currentversion);
		if (true == firstTime) {
			HoverTranslate.log('FirstTime');
			setTimeout(function() {
				HoverTranslate.openFirstTime();
			}, 400);
			HoverTranslate.prefManager.setBoolPref(
					"extensions.hovertranslate.first.time", false);
			//for the first time get the user language from locale
			HoverTranslate.log(HoverTranslate.prefManager.getCharPref("general.useragent.locale").split('-')[0]);
			localLanguage=HoverTranslate.prefManager.getCharPref("general.useragent.locale").split('-')[0];
			HoverTranslate.prefManager.setCharPref("extensions.hovertranslate.language", localLanguage);
			HoverTranslate.prefManager.setCharPref("extensions.hovertranslate.never.language", localLanguage);
		} else if (currentversion != Constants.version) {
			HoverTranslate.log('Different Version');
			setTimeout(function() {
				HoverTranslate.openFirstTime(true);
			}, 400);
			HoverTranslate.prefManager.setCharPref(
					"extensions.hovertranslate.version", Constants.version);
		}
		// Send request to get the detection key
		var detectKeyRequest = Components.classes["@mozilla.org/xmlextras/xmlhttprequest;1"]
				.createInstance(Components.interfaces.nsIXMLHttpRequest);
		detectKeyRequest.onload = function(aEvent) {
			var detectKeyJsonText = aEvent.target.responseText;
			var jsDetectKeyObject = JSON.parse(detectKeyJsonText);
			HoverTranslate.detectKey = jsDetectKeyObject.detectData.key;
			HoverTranslate.log('detectKey ' + HoverTranslate.detectKey);
			HoverTranslate.enabled = jsDetectKeyObject.detectData.enabled;
		};
		if (HoverTranslate.detectKey == null) {
			HoverTranslate.log('before send detectKey ');
			detectKeyRequest.open("GET", Constants.detectKeyURL, true);
			detectKeyRequest.send(null);
		}
		// end getting the detection key
		var container = gBrowser.tabContainer;
		var firstTab = container.childNodes[0];
		var browser = gBrowser.getBrowserForTab(firstTab);
		browser.removeEventListener("mousemove", HoverTranslate.mouseMoved,	false);
		browser.removeEventListener("mouseover", HoverTranslate.mousein, false);
		browser.removeEventListener("mouseout", HoverTranslate.mouseout, false);
		browser.addEventListener("mousemove", HoverTranslate.mouseMoved, false);
		browser.addEventListener("mouseover", HoverTranslate.mousein, false);
		browser.addEventListener("mouseout", HoverTranslate.mouseout, false);
		container.addEventListener("TabOpen", HoverTranslate.tabOpened, false);
		container.addEventListener("TabClose", HoverTranslate.tabClosed, false);


	},
	openFirstTime : function(isDifferentVersion) {
		HoverTranslate.log('openFirstTime1');
		var redirectURL = Constants.newURL;
		if (true == isDifferentVersion) {
			HoverTranslate.log('openFirstTime Different Version');
			redirectURL = Constants.updateURL;
		}
		HoverTranslate.newTab(redirectURL);
	},
	appendError : function(str) {
		throw new Error("DEBUG: " + str);
	},
	log : function(str) {
		if (Constants.logging == true) {
			setTimeout(function() {
				HoverTranslate.appendError(str.trim().replace("\"", " ")
						.replace("\'", " "));
			}, 1);
		}
	},
	mouseMoved : function(event) {
		var enable = HoverTranslate.isEnabled();
		// HoverTranslate.log('enable '+enable);
		if (enable == true) {
			HoverTranslate.wordTarget = event.target;
		//	HoverTranslate.hideTranslation();
			window.content.document.body.style.cursor = 'default';
			var browser = gBrowser.selectedBrowser;
			var scrollLeft = browser.contentDocument.documentElement.scrollLeft;
			var scrollTop = browser.contentDocument.documentElement.scrollTop;
			// HoverTranslate.log('scrollLeft '+scrollLeft);
			// HoverTranslate.log('scrollTop '+scrollTop);
			// HoverTranslate.log('window.pageXOffset '+window.pageXOffset);
			// HoverTranslate.log('window.pageYOffset '+window.pageYOffset);
			// HoverTranslate.log('browser.contentDocument.body.scrollLeft'+browser.contentDocument.body.scrollLeft);
			// HoverTranslate.log('browser.contentDocument.body.scrollTop'+browser.contentDocument.body.scrollTop);
			if (scrollLeft == 0 && browser.contentDocument.body != null) {
				scrollLeft = browser.contentDocument.body.scrollLeft;
			}
			if (scrollTop == 0 && browser.contentDocument.body != null) {
				scrollTop = browser.contentDocument.body.scrollTop;
			}
			HoverTranslate.localx = event.clientX;
			HoverTranslate.localy = event.clientY;
			HoverTranslate.x = event.clientX + scrollLeft;
			HoverTranslate.y = event.clientY + scrollTop;
			//HoverTranslate.log('transvisible= '+HoverTranslate.trans_visible);
			//HoverTranslate.log('time= '+HoverTranslate.timer);
			if (HoverTranslate.timer == null && HoverTranslate.trans_visible == false) {
				HoverTranslate.log('setInterval ');
				HoverTranslate.timer = setInterval(function() {
					HoverTranslate.checkMove();
				}, Constants.timeout);
			}
		}
	},
	getWordAtPoint : function(elem, x, y) {
		// HoverTranslate.log('getWordAtPoint ');
		if (elem.nodeType == elem.TEXT_NODE) {
			HoverTranslate.log('getWordAtPoint TEXT NODE');
			var range = elem.ownerDocument.createRange();
			range.selectNodeContents(elem);
			var currentPos = 0;
			var endPos = range.endOffset;
			// substringing
			var string = range.toString();
			HoverTranslate.log('the string is ' + string);
			while (currentPos + 1 < endPos) {
				range.setStart(elem, currentPos);
				range.setEnd(elem, currentPos + 1);
				if (range.getBoundingClientRect().left <= x
						&& range.getBoundingClientRect().right >= x
						&& range.getBoundingClientRect().top <= y
						&& range.getBoundingClientRect().bottom >= y) {
					var startString = string.substr(0, currentPos);
					HoverTranslate.log('start string is ' + startString);
					var start = startString.lastIndexOf(' ');
					HoverTranslate.log('start space  ' + start);
					var end = (string.indexOf(' ', currentPos) > -1) ? (string
							.indexOf(' ', currentPos)) : (string.length);
					HoverTranslate.log('end space  ' + end);
					range.setStart(elem, start + 1);
					range.setEnd(elem, end);
					var ret = range.toString();
					range.detach();
					return (ret);
				}
				currentPos += 1;
			}
		} else {
			HoverTranslate.log('getWordAtPoint in else ');
			for ( var i = 0; i < elem.childNodes.length; i++) {
				HoverTranslate.log('getWordAtPoint in else the elements '
						+ elem.childNodes.length);
				var range = elem.childNodes[i].ownerDocument.createRange();
				range.selectNodeContents(elem.childNodes[i]);
				if (range.getBoundingClientRect().left <= x
						&& range.getBoundingClientRect().right >= x
						&& range.getBoundingClientRect().top <= y
						&& range.getBoundingClientRect().bottom >= y) {
					range.detach();
					HoverTranslate.log('getWordAtPoint in else found elemtn '
							+ elem.childNodes[i]);
					return (HoverTranslate.getWordAtPoint(elem.childNodes[i],
							x, y));
				} else {
					range.detach();
				}
			}
		}
		return (null);
	},
	checkMove : function() {
		var enable = HoverTranslate.isEnabled();
		if (enable == true) {
			if (HoverTranslate.x == HoverTranslate.x2
					&& HoverTranslate.y == HoverTranslate.y2) {
				
				var browser = gBrowser.selectedBrowser;
				// HoverTranslate.log('the target '+HoverTranslate.wordTarget);
				var word = HoverTranslate.getWordAtPoint(
						HoverTranslate.wordTarget, HoverTranslate.localx,
						HoverTranslate.localy);
				HoverTranslate.log('the word is ' + word);
				HoverTranslate.log('clear interval');
				clearInterval(HoverTranslate.timer);
				HoverTranslate.timer = null;
				if (word != null) {
					var toLang = HoverTranslate.prefManager
							.getCharPref("extensions.hovertranslate.language");
					var neverFrom = HoverTranslate.prefManager
							.getCharPref("extensions.hovertranslate.never.language");
					// HoverTranslate.log('toLang '+toLang);
					// HoverTranslate.log('neverFrom '+neverFrom);
					var translation = HoverTranslate.translate(word, toLang,
							neverFrom);
				}
			} else {
				HoverTranslate.x2 = HoverTranslate.x;
				HoverTranslate.y2 = HoverTranslate.y;
			}
		}
	},
	mousein : function(event) {
		var enable = HoverTranslate.isEnabled();
		if (enable == true) {
			var browser = gBrowser.selectedBrowser;
			if (event.target == browser) {
				//if there is no timer set and the translation div in not displayed
				if (HoverTranslate.timer == null && HoverTranslate.trans_visible == false) {
					HoverTranslate.log('setInterval mousein');
					HoverTranslate.timer = setInterval(function() {
						HoverTranslate.checkMove();
					}, Constants.timeout);
				}
			}
		}
	},
	mouseout : function(event) {
		var enable = HoverTranslate.isEnabled();
		if (enable == true) {
			var browser = gBrowser.selectedBrowser;
			if (event.target == browser) {
				HoverTranslate.log('mouseout');
				clearInterval(HoverTranslate.timer);
				HoverTranslate.timer = null;
			}
		}
	},
	tabOpened : function(event) {
		HoverTranslate.log('tabOpened');
		var browser = gBrowser.getBrowserForTab(event.target);
		if (browser.contentDocument.body != null) {
			browser.removeEventListener("mousemove", HoverTranslate.mouseMoved,
					false);
			browser.removeEventListener("mouseover", HoverTranslate.mousein,
					false);
			browser.removeEventListener("mouseout", HoverTranslate.mouseout,
					false);
			HoverTranslate.log('events before');
			browser.addEventListener("mousemove", HoverTranslate.mouseMoved,
					false);
			browser
					.addEventListener("mouseover", HoverTranslate.mousein,
							false);
			browser
					.addEventListener("mouseout", HoverTranslate.mouseout,
							false);
		}
		HoverTranslate.log('events added');
	},
	tabClosed : function(event) {
		HoverTranslate.log('tabClosed');
		var browser = gBrowser.getBrowserForTab(event.target);
		if (browser != null) {
			browser.removeEventListener("mousemove", HoverTranslate.mouseMoved,
					false);
			browser.removeEventListener("mouseover", HoverTranslate.mousein,
					false);
			browser.removeEventListener("mouseout", HoverTranslate.mouseout,
					false);
		}
		HoverTranslate.log('events removed');
	},
	showTranslation : function(translationText) {
		HoverTranslate.log('HoverTranslate.x ' + HoverTranslate.x);
		HoverTranslate.log('HoverTranslate.y ' + HoverTranslate.y);
		var toLang = HoverTranslate.prefManager
				.getCharPref("extensions.hovertranslate.language");
		var dir = 'ltr';
		if (toLang == "ar" || toLang == "he" || toLang == "fa"
				|| toLang == "ur") {
			dir = 'rtl';
		}
		window.content.document.body.style.cursor = 'default';
		var find_more_text=Constants.search_en;
		if("ar" == toLang || "en" == toLang || "ru" == toLang || "fr" == toLang || "de" == toLang)
			{
			 find_more_text=eval("Constants.search_"+toLang);
			}

		var divx = HoverTranslate.x + 20;
		var divy = HoverTranslate.y;
		var text_length=(find_more_text.length+translationText.length);
		var width = 20 + text_length * 6;
		var height = (Math.floor(text_length / 20) + ((text_length % 20) == 0 ? 0
				: 1)) * 40;
		divy = divy - height;
		if(divy<0)
			{
				divy=0;
			}

		var div = window.content.document.getElementById('translationDiv');
		if (div == null) {
			HoverTranslate.log('showTranslation the div is null ' +div);
			div = document.createElement('div');
			div.setAttribute('id', 'translationDiv');
			div.setAttribute('style', 'font-family:Arial,Helvetica,sans-serif;font-size:15px;');
			div.style.background = "#fff";
			div.style.color = "#000";
			div.style.position = "absolute";
			div.style.border = "2px solid #888";
			div.style.display='inline-block';
			div.style.zIndex = "1000000";
			div.style.cursor = "pointer";

		}

		div.style.direction = dir;
		div.style.left = divx + 'px';
		div.style.top = divy + 'px';
		if (div.hasChildNodes()) {
			for ( var index = 0; index < div.childNodes.length; index++) {
				div.removeChild(div.childNodes[index]);
			}
		}


		var translation_div=document.createElement("div");
		translation_div.appendChild(document.createTextNode("<"+HoverTranslate.translation+">  ====>  "));
		translation_div.style.color="#555544";

		var link_text=document.createTextNode(find_more_text+HoverTranslate.translation);
		var link=document.createElement("div");
		link.style.color = "#5555ff";
		link.appendChild(link_text);


		div.onclick=HoverTranslate.search_click;
		div.appendChild(translation_div);
		div.appendChild(link);
		div.style.visibility = 'visible';

		window.content.document.body.appendChild(div);
		HoverTranslate.trans_visible=true;
	},
	hideTranslation : function() {
		var div = window.content.document.getElementById('translationDiv');
		if (div != null && div.style.visibility != 'hidden') {
			div.style.visibility = 'hidden';
			if (div.hasChildNodes()) {
				for ( var index = 0; index < div.childNodes.length; index++) {
					div.removeChild(div.childNodes[index]);
				}
			}
		}
		HoverTranslate.trans_visible=false;
	},
	translate : function(text, targetLang, neverFrom) {
		var detectResult = "";
		if (HoverTranslate.enabled != "true") {
			HoverTranslate.log('addonEnabled ' + addonEnabled);
			return "";
		}
		// HoverTranslate.log('detectURL '+detecturl);
		var detecturl = Constants.detectURL + encodeURIComponent(text) + "&key="
				+ encodeURIComponent(HoverTranslate.detectKey);
		var detectRequest = Components.classes["@mozilla.org/xmlextras/xmlhttprequest;1"]
				.createInstance(Components.interfaces.nsIXMLHttpRequest);
		// HoverTranslate.log('detectURL '+detecturl);
		detectRequest.onload = function(aEvent) {
			// HoverTranslate.log('detectRequest.onload ');
			var detectJsonText = aEvent.target.responseText;
			var jsDetectObject = JSON.parse(detectJsonText);
			detectResult = jsDetectObject.data.detections[0].language;
			HoverTranslate.log('detectResult ' + detectResult);
			if (neverFrom == detectResult || targetLang == detectResult
					|| detectResult.length > 2 || detectResult.length < 2) {
				return '';
			} else {
				window.content.document.body.style.cursor = 'wait';
				var translateURL = Constants.translateURL + encodeURIComponent(text) + "&langpair="
						+ encodeURIComponent(detectResult) + "|" + encodeURIComponent(targetLang);
				HoverTranslate.log('translateURL ' + translateURL);
				var translateRequest = Components.classes["@mozilla.org/xmlextras/xmlhttprequest;1"]
						.createInstance(Components.interfaces.nsIXMLHttpRequest);
				translateRequest.onload = function(aEvent) {
					// HoverTranslate.log('translateRequest.onload ');
					var translateJsonText = aEvent.target.responseText;
					HoverTranslate
							.log('translateJsonText ' + translateJsonText);
					var translateJson = JSON.parse(translateJsonText);
					HoverTranslate.translation = translateJson.responseData.translatedText;
					HoverTranslate.log('The translation is '
							+ HoverTranslate.translation);
					HoverTranslate.showTranslation(HoverTranslate.translation);
				};
				translateRequest.onerror = function(aEvent) {
					HoverTranslate.translation = aEvent.target.status;
					// HoverTranslate.log('translateRequest error
					// '+aEvent.target.status);
				};
				if (HoverTranslate.x == HoverTranslate.x2
						&& HoverTranslate.y == HoverTranslate.y2) {
					HoverTranslate.log('Sending translate request');
					translateRequest.open("GET", translateURL, true);
					translateRequest.send(null);
				}
			}
		};
		detectRequest.onerror = function(aEvent) {
			HoverTranslate.translation = aEvent.target.status;
			// HoverTranslate.log('detectRequest error
			// '+aEvent.target.status);
		};
		if (HoverTranslate.x == HoverTranslate.x2
				&& HoverTranslate.y == HoverTranslate.y2
				&& HoverTranslate.detectKey != null) {
			HoverTranslate.log('Sending detect request');
			detectRequest.open("GET", detecturl, true);
			detectRequest.send(null);
		}
	},
	isEnabled : function() {
		var enable = HoverTranslate.prefManager
				.getBoolPref("extensions.hovertranslate.enable");
		return enable;
	}
	,
	click : function(){
		HoverTranslate.log('clicked ');
		HoverTranslate.hideTranslation();

		}
	,
	search_click : function(){
		HoverTranslate.log('search clicked ');
		HoverTranslate.hideTranslation();
		HoverTranslate.newTab(Constants.search_URL+encodeURIComponent(HoverTranslate.translation));

		}
	,
	newTab : function(url)
	{
		var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"]
		.getService(Components.interfaces.nsIWindowMediator);
		HoverTranslate.log('openFirstTime');
		var mainWindow = wm.getMostRecentWindow("navigator:browser");
		mainWindow.gBrowser.selectedTab = getBrowser().addTab(url);
	}
	,
	createTable : function(translation_text, find_more_text)
	{
		var table=document.createElement('table');
		var translation_row=document.createElement('tr');
		var translation_td=document.createElement('td');
		var find_more_row=document.createElement('tr');
		var find_more_td=document.createElement('td');
		translation_td.appendChild(document.createTextNode(translation_text));
		find_more_td.appendChild(document.createTextNode(find_more_text));
		translation_row.appendChild(translation_td);
		find_more_row.appendChild(find_more_td);
		table.appendChild(translation_row);
		table.appendChild(find_more_row);

		return table;

	}

};
window.addEventListener("load", HoverTranslate.load, false);
window.addEventListener("click", HoverTranslate.click, false);